home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-01-11 | 17.2 KB | 464 lines | [TEXT/pdos] |
- Apple II
- Technical Notes
- _____________________________________________________________________________
- Developer Technical Support
-
-
- Apple IIGS
- #3: Window Information Bar Use
-
- Revised by: Dave Lyons January 1991
- Written by: Dan Oliver October 1986
-
- This Technical Note details the use of a window's information bar, includinga
- code sample which places a menu in an information bar.
- Changes since November 1988: Added a note about the current Resource
- Application when inside an InfoDefProc procedure, and information about
- information bars and NewWindow2.
-
- _____________________________________________________________________________
-
- Apple IIGS window information bars are not as straightforward as other window
- features, and one reason for this is the small amount of space originally
- allocated for their processing. If you feel your application can benefitfrom
- the use of information bars, you can implement them, and this Technical Note
- explains how to do it and includes some suggestions for their use. The code
- samples below demonstrate how to place a menu bar in an information bar, but
- your use of information bars is not limited to those described here.
-
-
- Information Bar Initialization
-
- You can create an information bar in a window when you create the window by
- setting the following fields in the parameter list you pass to NewWindow:
-
- wFrame Set bit 4.
-
- wInfoHeight Set to the height of the information bar (should not exceed
- window height).
-
- wInfoDefProc Set to the address of the information bar definition
- procedure (see below).
-
- If you create a window as visible, the Window Manager will call your
- information bar definition procedure (InfoDefProc) before returning from
- NewWindow. If you have to create the contents of the information bar after
- the window, you will have a problem since the Window Manager will expect your
- InfoDefProc to draw things which do not yet exist. You can solve this problem
- by creating the window as invisible, creating the contents of the information
- bar, then showing the window. Another solution would be to detect, in the
- InfoDefProc, that the contents of the information bar do not yet exist.
-
- NewWindow2, however, does not let you override the information bar drawing
- procedure in the template. If you pass a window template in a resource,
- creating the window as visible crashes (since the address of your information
- bar drawing procedure cannot possibly be in the window template resource).
- Instead, create the window as invisible and call SetInfoDraw to set the address
- of the information bar drawing procedure before calling ShowWindow.
-
- Below is an example of initializing a window's information bar to contain a
- menu bar. The three key fields of the parameter list which you pass to
- NewWindow are as follows:
-
- wFrame Set bit 4 = 1 and bit 5 = 0 for an invisible window; the
- other bits do not affect the information bar, so you can set
- them as you wish.
-
- wInfoHeight Assuming you are using a system menu bar and initializing it
- before the window, set to the height FixMenuBar returned
- when you created the system menu bar. If you would rather
- use an absolute value, which we do not advise, you could use
- 14 which should be about right for the current system font.
-
- wInfoDefProc Set to the address of the InfoDefProc, in this case
- draw_info.
-
- After you create the window, but before you show it, you can create the menu
- bar to place in the information bar. The code to create the menu bar might
- look like the following:
-
- window Direct page location that contains pointer to window's port.
- ;
- ; --- Create a menu bar
- --------------------------------------------------------------------
- ;
- pha Space for result.
- pha
- pea $FFFF Set "use current port" flag.
- pea $FFFF
- _NewMenuBar Create a menu bar.
- pla Get returned menu bar handle.
- sta <menuBar Remember menu bar handle.
- pla
- sta <menuBar+2
- ;
- ;
- ; --- Store menu bar's handle in the window's InfoRefCon
- -----------------------------------
- ;
- pei <menuBar+2 Pass menu bar handle.
- pei <menuBar
- pei <window+2 Window to set refCon.
- pei <window
- _SetInfoRefCon Store menu bar handle in window's
- infoRefCon.
- ;
- ;
- ; --- Make the window's menu bar the current menu bar
- --------------------------------------
- ;
- pei <menuBar+2 Pass menu bar handle.
- pei <menuBar
- _SetMenuBar Make new menu bar the current menu bar.
-
- ;
- ;
- ; --- Get the RECT of the window's information bar
- -----------------------------------------
- ;
- pea tempRect|-16 Pass pointer of RECT.
- pea tempRect
- pei <window+2 Pass pointer of window.
- pei <window
- _GetRectInfo tempRect = interior RECT of window's
- Info Bar.
-
-
- ; --- Dereference menu bar handle
- ----------------------------------------------------------
- ;
- ldy #2
- lda [menuBar],y
- tay
- lda [menuBar]
- sta <menuBar Now menuBar is the pointer to the Menu
- Bar.
- sty <menuBar+2
- ;
- ;
- ; --- Set size of menu bar
- -----------------------------------------------------------------
- ;
- ;
- lda <tempRect+y1
- dec a Overlap top side.
- ldy #CtlRect+y1
- sta [menuBar],y
- ;
- lda <tempRect+x1
- dec a Overlap left side.
- ldy #CtlRect+x1
- sta [menuBar],y
- ;
- lda <rect+y2
- inc a Overlap bottom side.
- ldy #CtlRect+y2
- sta [menuBar],y
- ;
- ;
- ; --- Set flag to tell Menu Manager to draw menu in current port
- ---------------------------
- ;
- ldy #CtlOwner+2 Set high bit in CtlOwner.
- lda [menuBar],y
- ora #$8000
- sta [menuBar],y
- ;
- ;
- ; --- Create the menus and add them to the window's menu bar
- -------------------------------
- ;
- lda #4
- loop pha Save index into menu list.
- tay Switch index to Y.
- ;
- pha Space for return value.
- pha
- lda menu_list+2,y Pass address of menu/item lines.
- pha
- lda menu_list,y
- pha
- _NewMenu
- ; Menu handle already on stack.
- pea 0 Insert menu list at front of list.
- _InsertMenu Add my menus to the system menu bar.
- ;
- pla
- sec
- sbc #4
- bpl loop
- ;
- ;
- ; --- Initialize the size of the menu bar and menus
- ----------------------------------------
- ;
- pha Space for returned bar height.
- _FixMenuBar Fix up positions in the menu bar.
- pla Discard height of menu bar.
- ;
- ;
- ; --- Restore the system menu bar as the current menu
- --------------------------------------
- ;
- pea 0 Pass flag for system menu bar.
- pea 0
- _SetMenuBar Make system menu bar current.
-
- The window's menu bar is now initialized, and you can make the window visible
- with a call to ShowWindow; the InfoDefProc will draw the menu bar.
-
-
- Information Bar Definition Procedure (InfoDefProc)
-
- The InfoDefProc is slightly misleading; it is only responsible for drawing the
- interior, above the background, of the information bar. The InfoDefProc is not
- responsible for defining the information bar, drawing the frame and background,
- testing for hits, or tracking the user. The InfoDefProc is located inside your
- application, and the Window Manager calls it whenever it needs to draw the part
- of the window frame that contains the information bar.
- Each window with an information bar can have its own InfoDefProc, or they can
- all share a common InfoDefProc. When the Window Manager calls your InfoDefProc,
- it sets the proper port, the Window Manager's port, and the proper state, an
- origin local to the window frame and clipped to any windows above it. The
- direct page and data bank are not defined and should be considered unknown.
-
- The Window Manager passes your InfoDefProc the following information:
-
- o Pointer to the information bar's interior rectangle (less frame), local
- coordinates.
- o Value of the window's wInfoRefCon, set and used only by your application.
- o Pointer to the window's port (do not switch to this port for drawing).
-
- A window that has an information bar containing a menu bar (handle stored in the
- window's InfoRefCon) might have a InfoDefProc as follows:
-
- draw_info START
- ;
- theWindow equ 6 Offset to the information bar owner window
- infoRefCon equ theWindow+4 Offset to the window's information bar RefCon
- infoRect equ infoRefCon+4 Offset to the information bar's enclosing RECT
- ;
- phd Save original direct page.
- tsc Switch to direct page in stack.
- tcd
- ;
- ;
- ; --- Draw the window's menu bar in the window's information bar
- ---------------------------
- ;
- pei infoRefCon+2 Pass handle of window's menu bar handle.
- pei infoRefCon
- _SetMenuBar Make the window's menu bar the current menu
- bar.
- ;
- _DrawMenuBar Draw the window's menu bar, as requested.
- ;
- lda #0 Zero is the flag for the system menu bar.
- pha
- pha
- _SetMenuBar Make the system menu bar current again.
- ;
- ;
- ; --- Remove input parameters from the stack
- -----------------------------------------------
- ; ldx #12
- ply Pull original direct page, save in Y.
- ;
- tsc Move direct page point to stack.
- tcd
- lda 2,s Move return address over input parameters.
- sta 2,x
- lda 0,s
- sta 0,x
- ;
- tsc Adjust stack for stripped input parameters.
- phx Number of bytes of input parameters.
- clc
- adc 1,s Add number of input parameters to stack
- pointer.
- tcs And reset stack.
- ;
- tya Restore original direct page.
- tcd
- ;
- rtl Return to Window Manager.
- END
-
-
- Information Bar Environment
-
- An information bar is part of a window's frame, that is, not part of the
- window's content region. Because it is part of the frame, an information bar
- is in the Window Manager's port, so before an interaction (drawing or mouse
- selecting), the proper port (Window Manager's) must be in the proper state.
- The proper state means the origin must be at the window's upper-left corner
- and clipped to any windows above.
-
- When the Window Manager calls the InfoDefProc it sets the proper port to the
- proper state; however, to interact with the information bar outside the
- InfoDefProc, you must set the proper port the the proper state. You can
- accomplish this with a call to StartInfoDrawing. When the interaction is
- completed, you must allow the Window Manager to return its port to a general
- state via a call to EndInfoDrawing. You are in a special state that requires
- some constraints (discussed later) between the calls to StartInfoDrawing and
- EndInfoDrawing.
-
- Here is an example of interacting with our window's menu bar.
-
- ;
- poll pha Space for return value.
- pea %0000111101101110 Pass event mask to use.
- pea TaskRec|-16 Pass pointer to Task record.
- pea TaskRec
- _TaskMaster
- pla Get returned value.
- beq poll Does event need further processing?
- ;
- ;
- ; --- Handle button down in window's information bar
- ---------------------------------------
- ;
- cmp #InInfo In Information bar?
- bne poll
- ;
- pha Space for result.
- pha
- lda TaskRec+TaskData+2 Pass pointer of window.
- pha
- lda TaskRec+TaskData
- pha
- _GetInfoRefCon Get menu bar handle from window's
- InfoRefCon.
- pla
- sta menuBar
- pla
- sta menuBar+2
- ;
- ;
- ; --- Switch to proper port in proper coordinate system
- ------------------------------------
- ;
- pea tempRect|-16 Pass pointer to RECT to store info
- bar RECT.
- pea tempRect
- lda TaskRec+TaskData+2 Pass pointer of window.
- pha
- lda TaskRec+TaskData
- pha
- _StartInfoDrawing
- ;
- ;
- ; --- Handle menu selection from window's menu bar
- -----------------------------------------
- ;
- pea TaskRec|-16 Pass pointer to Task record for
- MenuSelect.
- pea TaskRec
- pei menuBar+2 Pass handle of menu bar.
- pei menuBar
- _MenuSelect Let user make selection.
- ;
- lda event+TaskData Get the item's ID number.
- beq exit Was a selection made?
- ;
- _EndInfoDrawing Switch back to original port.
-
- ;
- ; (Handle the menu selection.)
- ;
- ; The EndInfoDrawing followed by the StartInfoDrawing call is only
- ; needed when code between them calls the Window Manager.
- ;
- pea tempRect|-16 Pass pointer to RECT to store info
- bar RECT.
- pea tempRect
- lda TaskRec+TaskData+2 Pass pointer of window.
- pha
- lda TaskRec+TaskData
- pha
- _StartInfoDrawing Switch to the proper port in the
- proper state.
- ;
- pea 0 Pass unhilite flag.
- lda TaskRec+TaskData+2 Pass menu's ID number.
- pha
- _HiliteMenu Unhilite menu's title.
- ;
- ;
- ; --- Clean up and return to polling
- -------------------------------------------------------
- ;
- exit _EndInfoDrawing Switch back to original port.
- ;
- pea 0 Make system menu bar current.
- pea 0
- _SetMenuBar
- ;
- jmp poll Return to polling user.
- ;
-
-
- Information Bar Shutdown
-
- When the Window Manager closes the window, it is up to you to resolve any
- shutdown necessities associated with the information bar. Using our window
- menu bar example, the close window might look like the following:
-
- ;
- pei menuBar+2 Pass handle of menu bar
- pei menuBar
- _SetMenuBar
- ;
- pha Space for returned menu handle.
- pha
- pea 2 ID number of second menu.
- _GetMHandle Get the menu's handle.
- _DisposeMenu Free menu record and associated data.
- ;
- pha Space for returned menu handle.
- pha
- pea 1 ID number of first menu.
- _GetMHandle Get the menu's handle.
- _DisposeMenu Free menu record and associated data.
- ;
- pea 0 Make system menu bar current.
- pea 0
- _SetMenuBar
- ;
- pha Space for menu bar's handle.
- pha
- pei <window+2 Pass pointer of window to close.
- pei <window
- _GetInfoRefCon Get the InfoRefCon from the window.
- _DisposeHandle Free menu bar record.
- ;
- pei <window+2 Pass pointer of window to close.
- pei <window
- _CloseWindow Now the window can be closed.
- ;
-
- The type of shutdown you use depends upon the contents of the informationbar.
-
- Why didn't I put a DisposeMenuBar call in the Menu Manager? I didn't thinkof it
- until a week too late. Sorry.
-
-
- Other Information Bar Uses
-
- The following suggestions are only theories and have not been tested.
-
- o Display text information, as in Macintosh Finder windows.
- o Split window. Like the content region, the information bar could be large
- enough to hold data.
- o Hold controls. You could scroll data in the content region while keeping
- the controls which affect the display in place and within the user's reach.
- (Note: The Control Manager currently will not allow controls it creates in
- an information bar. In this case, NewControl would be using a port that is
- not in your window's port, namely the Window Manager's port.)
-
-
- Further Reference
- _____________________________________________________________________________
- o Apple IIGS Toolbox Reference, Volumes 1 & 2
-
-